home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH16 / ARITH2.ASM < prev    next >
Encoding:
Assembly Source File  |  1994-07-11  |  6.5 KB  |  301 lines

  1. ; ARITH2.ASM
  2. ;
  3. ; A simple floating point calculator that demonstrates the use of the
  4. ; UCR Standard Library pattern matching routines.  Note that this
  5. ; program requires an FPU.
  6.  
  7.         .xlist
  8.         .386
  9.         .387
  10.         option        segment:use16
  11.         include     stdlib.a
  12.         includelib    stdlib.lib
  13.         matchfuncs
  14.         .list
  15.  
  16.  
  17. dseg        segment    para public 'data'
  18.  
  19. ; The following is a temporary used when converting a floating point
  20. ; string to a 64 bit real value.
  21.  
  22. CurValue    real8    0.0
  23.  
  24.  
  25. ; Some sample strings containing expressions to try out:
  26.  
  27.  
  28. Str1        byte    "5+2*(3-1)",0
  29. Str2        byte    "(5+2)*(7-10)",0
  30. Str3        byte    "5",0
  31. Str4        byte    "(6+2)/(5+1)-7e5*2/1.3e2+1.5",0
  32. Str5        byte    "2.5*(2-(3+1)/4+1)",0
  33. Str6        byte    "6+(-5*2)",0
  34. Str7        byte    "6*-1",0
  35. Str8        byte    "1.2e5/2.1e5",0
  36. Str9        byte    "0.9999999999999999+1e-15",0
  37. str10        byte    "2.1-1.1",0
  38.  
  39.  
  40. ; Grammar for simple infix -> postfix translation operation:
  41. ; Semantic rules appear in braces.
  42. ;
  43. ; E -> FE' {print result}
  44. ; E' -> +F {fadd} E' | -F {fsub} E' | <empty string>
  45. ; F -> TF'
  46. ; F -> *T {fmul} F' | /T {fdiv} F' | <empty string>
  47. ; T -> -T {fchs} | S
  48. ; S -> <constant> {fld constant} | (E)
  49. ;
  50. ;
  51. ;
  52. ; UCR Standard Library Pattern which handles the grammar above:
  53.  
  54. ; An expression consists of an "E" item followed by the end of the string:
  55.  
  56. Expression    pattern    {sl_Match2,E,,EndOfString}
  57. EndOfString    pattern    {EOS}
  58.  
  59.  
  60. ; An "E" item consists of an "F" item optionally followed by "+" or "-"
  61. ; and another "E" item:
  62.  
  63. E        pattern    {sl_Match2, F,,Eprime}
  64. Eprime        pattern    {MatchChar, '+', Eprime2, epf}
  65. epf        pattern    {sl_Match2, F,,epPlus}
  66. epPlus        pattern    {DoFadd,,,Eprime}
  67.  
  68. Eprime2        pattern    {MatchChar, '-', Succeed, emf}
  69. emf        pattern    {sl_Match2, F,,epMinus}
  70. epMinus        pattern    {DoFsub,,,Eprime}
  71.  
  72. ; An "F" item consists of a "T" item optionally followed  by "*" or "/"
  73. ; followed by another "T" item:
  74.  
  75. F        pattern    {sl_Match2, T,,Fprime}
  76. Fprime        pattern    {MatchChar, '*', Fprime2, fmf}
  77. fmf        pattern    {sl_Match2, T, 0, pMul}
  78. pMul        pattern    {DoFmul,,,Fprime}
  79.  
  80. Fprime2        pattern    {MatchChar, '/', Succeed, fdf}
  81. fdf        pattern    {sl_Match2, T, 0, pDiv}
  82. pDiv        pattern    {DoFdiv, 0, 0,Fprime}
  83.  
  84. ; T item consists of an "S" item or a "-" followed by another "T" item:
  85.  
  86. T        pattern    {MatchChar, '-', S, TT}
  87. TT        pattern    {sl_Match2, T, 0,tpn}
  88. tpn        pattern    {DoFchs}
  89.  
  90. ; An "S" item is either a floating point constant or "(" followed by
  91. ; and "E" item followed by ")".
  92. ;
  93. ; The regular expression for a floating point constant is
  94. ;
  95. ;    [0-9]+ ( "." [0-9]* | ) ( ((e|E) (+|-| ) [0-9]+) | )
  96. ;
  97. ; Note: the pattern "Const" matches exactly the characters specified
  98. ;    by the above regular expression.  It is the pattern the calc-
  99. ;    ulator grabs when converting a string to a floating point number.
  100.  
  101.  
  102. Const        pattern    {sl_match2, ConstStr, 0, FLDConst}
  103. ConstStr    pattern    {sl_match2, DoDigits, 0, Const2}
  104. Const2        pattern    {matchchar, '.', Const4, Const3}
  105. Const3        pattern    {sl_match2, DoDigits, Const4, Const4}
  106. Const4        pattern    {matchchar, 'e', const5, const6}
  107. Const5        pattern    {matchchar, 'E', Succeed, const6}
  108. Const6        pattern    {matchchar, '+', const7, const8}
  109. Const7        pattern    {matchchar, '-', const8, const8}
  110. Const8        pattern    {sl_match2, DoDigits}
  111.  
  112. FldConst    pattern    {PushValue}
  113.  
  114. ; DoDigits handles the regular expression [0-9]+
  115.  
  116. DoDigits    pattern    {Anycset, Digits, 0, SpanDigits}
  117. SpanDigits    pattern    {Spancset, Digits}
  118.  
  119. ; The S production handles constants or an expression in parentheses.
  120.  
  121. S        pattern    {MatchChar, '(', Const, IntE}
  122. IntE        pattern    {sl_Match2, E, 0, CloseParen}
  123. CloseParen    pattern    {MatchChar, ')'}
  124.  
  125.  
  126. ; The Succeed pattern always succeeds.
  127.  
  128. Succeed        pattern    {DoSucceed}
  129.  
  130.  
  131. ; We use digits from the UCR Standard Library cset standard sets.
  132.  
  133.         include    stdsets.a
  134.  
  135. dseg        ends
  136.  
  137.  
  138.  
  139. cseg        segment    para public 'code'
  140.         assume    cs:cseg, ds:dseg
  141.  
  142. ; DoSucceed matches the empty string.  In other words, it matches anything
  143. ; and always returns success without eating any characters from the input
  144. ; string.
  145.  
  146. DoSucceed    proc    far
  147.         mov    ax, di
  148.         stc
  149.         ret
  150. DoSucceed    endp
  151.  
  152.  
  153. ; DoFadd - Adds the two items on the top of the FPU stack.
  154.  
  155. DoFadd        proc    far
  156.         faddp    st(1), st
  157.         mov    ax, di            ;Required by sl_Match
  158.         stc                ;Always succeed.
  159.         ret
  160. DoFadd        endp
  161.  
  162.  
  163. ; DoFsub - Subtracts the two values on the top of the FPU stack.
  164.  
  165. DoFsub        proc    far
  166.         fsubp    st(1), st
  167.         mov    ax, di            ;Required by sl_Match
  168.         stc
  169.         ret
  170. DoFsub        endp
  171.  
  172.  
  173. ; DoFmul- Multiplies the two values on the FPU stack.
  174.  
  175. DoFmul        proc    far
  176.         fmulp    st(1), st
  177.         mov    ax, di            ;Required by sl_Match
  178.         stc
  179.         ret
  180. DoFmul        endp
  181.  
  182.  
  183. ; DoFdiv- Divides the two values on the FPU stack.
  184.  
  185. DoFDiv        proc    far
  186.         fdivp    st(1), st
  187.         mov    ax, di            ;Required by sl_Match
  188.         stc
  189.         ret
  190. DoFDiv        endp
  191.  
  192.  
  193. ; DoFchs- Negates the value on the top of the FPU stack.
  194.  
  195. DoFchs        proc    far
  196.         fchs
  197.         mov    ax, di            ;Required by sl_Match
  198.         stc
  199.         ret
  200. DoFchs        endp
  201.  
  202.  
  203. ; PushValue-    We've just matched a string that corresponds to a
  204. ;        floating point constant.  Convert it to a floating
  205. ;        point value and push that value onto the FPU stack.
  206.  
  207. PushValue    proc    far
  208.         push    ds
  209.         push    es
  210.         pusha
  211.         mov    ax, dseg
  212.         mov    ds, ax
  213.  
  214.         lesi    Const        ;FP val matched by this pat.
  215.         patgrab            ;Get a copy of the string.
  216.         atof            ;Convert to real.
  217.         free            ;Return mem used by patgrab.
  218.         lesi    CurValue    ;Copy floating point accumulator
  219.         sdfpa            ; to a local variable and then
  220.         fld    CurValue    ; copy that value to the FPU stk.
  221.  
  222.         popa
  223.         mov    ax, di
  224.         pop    es
  225.         pop    ds
  226.         stc
  227.         ret
  228. PushValue    endp
  229.  
  230.  
  231.  
  232. ; DoExp-    This routine expects a pointer to a string containing
  233. ;        an arithmetic expression in ES:DI.  It evaluates the
  234. ;        given expression and prints the result.
  235.  
  236. DoExp        proc    near
  237.         finit            ;Be sure to do this!
  238.         fwait
  239.  
  240.         puts            ;Print the expression
  241.  
  242.         ldxi    Expression
  243.         xor    cx, cx
  244.         match
  245.         jc    GoodVal
  246.         printff
  247.         byte    " is an illegal expression",cr,lf,0
  248.         ret
  249.  
  250. GoodVal:    fstp    CurValue
  251.         printff
  252.         byte    " = %12.6ge\n",0
  253.         dword    CurValue
  254.         ret
  255. DoExp        endp
  256.  
  257.  
  258.  
  259. ; The main program tests the expression evaluator.
  260.  
  261. Main        proc
  262.         mov    ax, dseg
  263.         mov    ds, ax
  264.         mov    es, ax
  265.         meminit
  266.  
  267.         lesi    Str1
  268.         call    DoExp
  269.         lesi    Str2
  270.         call    DoExp
  271.         lesi    Str3
  272.         call    DoExp
  273.         lesi    Str4
  274.         call    DoExp
  275.         lesi    Str5
  276.         call    DoExp
  277.         lesi    Str6
  278.         call    DoExp
  279.         lesi    Str7
  280.         call    DoExp
  281.         lesi    Str8
  282.         call    DoExp
  283.         lesi    Str9
  284.         call    DoExp
  285.         lesi    Str10
  286.         call    DoExp
  287.  
  288. Quit:        ExitPgm
  289. Main        endp
  290.  
  291. cseg        ends
  292.  
  293. sseg        segment    para stack 'stack'
  294. stk        db    1024 dup ("stack   ")
  295. sseg        ends
  296.  
  297. zzzzzzseg    segment    para public 'zzzzzz'
  298. LastBytes    db    16 dup (?)
  299. zzzzzzseg    ends
  300.         end    Main
  301.